/*
 *  Copyright 2011 Alexey Andreev.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package org.xthl.core;

import org.nop.core.Application;
import org.nop.core.BeanScope;
import org.nop.core.DefaultRemoteSession;
import org.nop.core.ManagedBean;
import org.nop.rmi.RmiSession;
import org.nop.sql.DataManager;
import org.nop.sql.DataResult;
import org.nop.sql.QueryBuilder;
import org.nop.util.Injected;
import org.xthl.core.api.AccountDisabledException;
import org.xthl.core.api.AuthenticationException;
import org.xthl.core.api.RestrictedAccessException;
import org.xthl.core.api.User;
import org.xthl.core.api.UserAuthenticator;
import org.xthl.core.data.UserSource;

/**
 *
 * @author Alexey Andreev
 */
@ManagedBean(iface = UserAuthenticator.class, scope = BeanScope.REQUEST)
public class UserAuthenticatorImpl implements UserAuthenticator {
    private Application app;
    private DataManager dataManager;
    private QueryBuilder qb;
    
    @Injected
    public UserAuthenticatorImpl(Application app, DataManager dataManager) {
        this.app = app;
        this.dataManager = dataManager;
        this.qb = dataManager.getQueryBuilder();
    }
    
    @Override
    public RmiSession login(String login, String password) throws AuthenticationException,
            AccountDisabledException, RestrictedAccessException {
        DefaultRemoteSession session = new DefaultRemoteSession();
        UserSource user = qb.get(UserSource.class);
        DataResult result = dataManager.exec(qb.with(user)
                .filter(user.login().eq(login))
                .fetch(user.id(), user.passwordHash(), user.enabled()));
        if (!result.next()) {
            throw new AuthenticationException(login);
        }
        if (!result.getBoolean(3)) {
            throw new AccountDisabledException(login);
        }
        if (!User.getPasswordHash(password).equals(result.getString(2))) {
            throw new AuthenticationException(login);
        }
        final int userId = result.getInt(1);
        session.register(UserSession.class, new UserSession() {
            @Override
            public int getUserId() {
                return userId;
            }
        });
        return app.exportSession(session);
    }
}
